﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using System.Collections;
using JEng_Mark_1.Interfaces;
using Microsoft.Xna.Framework.Graphics;
using JEng_Mark_1.Shaders;
using System.Threading;
using JEng_Mark_1.GameComponents;

namespace JEng_Mark_1.Managers
{
    public class JShaderManager : GameComponent
    {
        private static Dictionary<string, IJEngShader> _shaders = new Dictionary<string, IJEngShader>();

        private static int _shadersLoaded = 0;

        /// <summary>
        /// The number of shaders that are currently loaded,
        /// </summary>
        public static int ShadersLoaded { get { return _shadersLoaded; } }

        private static bool _initialized = false;

        /// <summary>
        /// Is the JShaderManager initialized
        /// </summary>
        public static bool Initialized { get { return _initialized; } }

        /// <summary>
        /// Create a new shader manager
        /// </summary>
        /// <param name="game">XNA Game</param>
        public JShaderManager(Game game) : base(game) { }

        /// <summary>
        /// Add a shader to the collection of loaded shaders
        /// </summary>
        /// <param name="newShader">Shader to add</param>
        /// <param name="shaderLabel">Name of shader for later reference</param>
        public static void AddShader(IJEngShader newShader, string shaderLabel)
        {
            if (shaderLabel != null && !_shaders.ContainsKey(shaderLabel))
            {
                _shaders.Add(shaderLabel, newShader);

                if (_initialized)
                {
                    ThreadStart threadStarter = delegate
                    {
                        newShader.Initialize(JEngineManager.Device);
                        _shadersLoaded++;
                        JLog.addMessage("Added new shader " + shaderLabel + " total shaders = " + _shadersLoaded);
                    };
                    Thread loadingThread = new Thread(threadStarter);
                    loadingThread.Start();
                }
            }
        }

        /// <summary>
        /// Get a shader by its name, returns null if name wasn't found in the collection
        /// </summary>
        /// <param name="shaderLabel">Name of shader to retrieve</param>
        /// <returns>The shader requested or null if the shader wasn't found.</returns>
        public static IJEngShader GetShader(string shaderLabel)
        {
            if (shaderLabel != null && _shaders.ContainsKey(shaderLabel))
            {
                return _shaders[shaderLabel];
            }
            return null;
        }

        public override void Initialize()
        {
            base.Initialize();

            AddShader(new JBasicEffect(), "BasicEffect");

            ThreadStart threadStarter = delegate
            {
                foreach (IJEngShader shader in _shaders.Values)
                {
                    if (!shader.ReadyToRender)
                    {
                        shader.Initialize(JEngineManager.Device);
                        _shadersLoaded++;
                    }
                }
            };
            Thread loadingThread = new Thread(threadStarter);
            loadingThread.Start();            

            _initialized = true;
        }
    }
}
